home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.04 Apr 91 / XCMD Apr Code < prev   
Encoding:
Text File  |  1991-02-21  |  9.2 KB  |  433 lines  |  [TEXT/nX^n]

  1. /************************************/
  2. /* A sample XCMD for Hypercard    */
  3. /* 2.0 that displays and handles    */
  4. /* external windows and dialogs.    */
  5. /*                        */
  6. /* Well-behaved XCMDs for HC2.0    */
  7. /* will respond to the ! and ?    */
  8. /* requests by returning version*/
  9. /* and usage information         */
  10. /* respectively.                */
  11. /*                        */
  12. /* ----------------------------    */
  13. /* ©1991, Donald Koscheka        */
  14. /* All Rights Reserved            */
  15. /************************************/
  16.  
  17. /*
  18.     Project:
  19.  
  20.         MacTraps
  21.         HyperXLib-- Hypercard 2.0 callback library available from 
  22.                 Apple Computer, Inc.
  23.                 
  24.         xwindoid.c (contents of listing 1)
  25.  
  26.     Set Project Type:
  27.         Type == XCMD | XFCN
  28.         Name == xwindoid
  29.         id     == -32768..32767
  30.         
  31.     Usage
  32.     
  33.         xwindoid "?"    -- XCMD 
  34.         xwindoid "!"
  35.         put the result
  36.         
  37.         OR              -- XFCN
  38.             
  39.         Put xwindoid( "?" )
  40.         Put xwindoid( "!" )
  41.         
  42.      Parameters:
  43.     
  44.         xwindoid "name", rect, style, dlgID
  45.         
  46.         name == the name of the window
  47.         rect == the rect of the window
  48.         style== dBoxProc, documentProc, palette, …
  49.         dlgID== dialog id( modal dialogs only).
  50. */
  51.  
  52. #include    <SetUpA4.h>
  53. #include    <string.h>
  54. #include    <HyperXCMD.h>
  55.  
  56. #ifndef    NIL
  57.     #define NIL    (void *)0L
  58. #endif
  59.  
  60. #define        ETX            0x03    
  61. #define        BS            0x08        
  62. #define        TAB            0x09
  63. #define        LF            0x0A
  64. #define        NEWLINE        0x0D
  65. #define        CR            0x0D
  66. #define        LEFT_ARROW        0x1C
  67. #define        RIGHT_ARROW        0x1D
  68. #define        UP_ARROW        0x1E
  69. #define        DOWN_ARROW        0x1F
  70.  
  71. /* Multifinder events and masks    */
  72. #ifndef    MouseMovedEvt
  73.     #define    MouseMovedEvt    0xFA    
  74. #endif
  75.  
  76. #ifndef    SuspendResumeEvt
  77.     #define    SuspendResumeEvt    0x01
  78. #endif
  79.  
  80. #ifndef    ResumeEvtMask
  81.     #define    ResumeEvtMask    0x01
  82. #endif
  83.  
  84. #ifndef    ConvertScrapMask
  85.     #define    ConvertScrapMask    0x02    
  86. #endif
  87.  
  88. #define    palette        0x80
  89.  
  90. pascal void HandleHCEvent( XCmdPtr    pp );
  91. pascal Boolean    modalFilter( DialogPtr dlg, EventRecord *evt, short *itemhit );
  92.  
  93. void    CenterWindow( WindowPtr    wptr, short isFront )
  94. /***************************
  95. * Center a window in the current
  96. * screen port.  Note: Does not
  97. * attempt to work with multi-screen
  98. * systems.
  99. *
  100. * This code is courtesy of Steve
  101. * Maller of Apple Computer Inc.
  102. * Thanks Steve.
  103. ***************************/
  104. {
  105.  short     hWindSize = wptr->portRect.right - wptr->portRect.left;
  106.  short    vWindSize = wptr->portRect.bottom - wptr->portRect.top;
  107.  short    hSize = wptr->portBits.bounds.right - wptr->portBits.bounds.left;
  108.  short    vSize = wptr->portBits.bounds.bottom - wptr->portBits.bounds.top;
  109.  
  110.  MoveWindow( wptr,     
  111.              ( hSize - hWindSize ) / 2, 
  112.              ( vSize - vWindSize + 20) / 2,
  113.             isFront
  114.         );
  115. }
  116.  
  117. void Concat( char    *str1, char    *str2 )
  118. /*****************************
  119. * Append string 2 to the end of
  120. * string 1.  Both strings are 
  121. * pascal-format strings.
  122. *
  123. * str1 must be large enough to hold
  124. * the new string and is assumed to 
  125. * be of Type Str255 (a pascal string)
  126. *****************************/
  127. {
  128.     BlockMove( str2 + 1, str1 + str1[0] + 1, (long)str2[0]);
  129.     str1[0] += str2[0];
  130. }
  131.  
  132. pascal void main( XCmdPtr    pp )
  133. /**************************************
  134. * MAIN ENTRYP POINT FOR THIS XCMD
  135. * params[0]    = the name of the window
  136. * params[1]    = the rect of the window (left,top,right,bottom)
  137. * params[2]    = the window style (dBoxProc, documentProc, palette)
  138. **************************************/
  139. {
  140.     Handle        answer    = NIL;
  141.     char        *str;
  142.     long        len;
  143.     WindowPtr    wind;
  144.     TEHandle    hTE;
  145.     Rect        bounds;
  146.     short        style        = documentProc;
  147.     char        title[32];
  148.     char        temp[64];        /* no need to hog the stack here */
  149.     long        dlgID         = 0;
  150.     
  151.     pp->returnValue = NIL;
  152.  
  153.     if( pp->paramCount < 0 ){    /* Have an event for one of our windows */
  154.         HandleHCEvent( pp );
  155.         return;
  156.     }
  157.     
  158.     if (pp->paramCount == 1){
  159.         if ( **(pp->params[0]) == '!' ){
  160.             pp->returnValue = PASTOZERO(pp,"\pxwindoid XCMD, version 1.1, ©1991, Donald Koscheka");
  161.             return;
  162.         }
  163.         
  164.         if ( **(pp->params[0]) == '?' ){
  165.             pp->returnValue = PASTOZERO(pp,"\pxwindoid name,rect,style");
  166.             return;
  167.         }
  168.     }
  169.     
  170.     /* if we get this far, the caller must be creating a new window */
  171.     title[0] = 0;    /* the default name */
  172.     Concat( title, "\pUntitled");
  173.     if( pp->params[0] ){
  174.         HLock( pp->params[0] );
  175.         ZEROTOPAS( pp, *(pp->params[0]), &title );
  176.         HUnlock( pp->params[0] );
  177.     }
  178.     
  179.     /* the default rectangle if one not specified */
  180.     bounds.top = bounds.left = 0;
  181.     bounds.bottom = 200;
  182.     bounds.right = 300;
  183.     if( pp->params[1] ){
  184.         HLock( pp->params[1] );
  185.         ZEROTOPAS( pp, *(pp->params[1]), &temp );
  186.         STRTORECT( pp, temp, &bounds );
  187.         HUnlock( pp->params[1] );
  188.     }
  189.     
  190.     if( pp->params[2] ){
  191.         HLock( pp->params[2] );
  192.         ZEROTOPAS( pp, *(pp->params[2]), &temp );
  193.         
  194.         /* the poor man's parser */
  195.         if( STRINGEQUAL( pp, temp, "\pDOCUMENTPROC" )) style = documentProc;
  196.         if( STRINGEQUAL( pp, temp, "\pDBOXPROC" )) style = dBoxProc;
  197.         if( STRINGEQUAL( pp, temp, "\pPALETTE" )) style = palette;
  198.         HUnlock( pp->params[2] );
  199.     }
  200.     
  201.     /* these callback will bomb if window is not valid */
  202.     XWALWAYSMOVEHIGH( pp, wind, TRUE );    
  203.     XWHASINTERRUPTCODE( pp, wind, TRUE );
  204.  
  205.     if( style == dBoxProc ){
  206.         GrafPtr    oldPort;
  207.         short    itemHit;
  208.         Handle    items;
  209.         
  210.         if( pp->params[3] ){
  211.             HLock( pp->params[3] );
  212.             ZEROTOPAS( pp, *(pp->params[3]), &temp );
  213.             dlgID = STRTONUM( pp, temp );
  214.             HUnlock( pp->params[3] );
  215.         }
  216.         
  217.         items = GetResource( 'DITL', dlgID );
  218.         DetachResource( items ); 
  219.         wind = NewDialog( NIL, &bounds, title, FALSE, dBoxProc,-1L,FALSE,0L, items );
  220.         CenterWindow( wind, TRUE );
  221.         GetPort( &oldPort );
  222.         SetPort( wind );
  223.         ShowWindow( wind );
  224.         
  225.         do{
  226.             ModalDialog( modalFilter, &itemHit );
  227.         }while( itemHit != OK );
  228.         
  229.         HideWindow( wind );
  230.         DisposDialog( wind );
  231.         SetPort( oldPort );
  232.     }
  233.     else{
  234.         wind = NEWXWINDOW( pp, &bounds, title, FALSE, style, 
  235.                                 FALSE, style==palette);
  236.         CenterWindow( wind, TRUE );
  237.     }
  238. }
  239.  
  240. pascal Boolean    modalFilter( DialogPtr dlg, EventRecord *evt, short *itemhit )
  241. /************************************
  242. * general filter proc, accepts return and
  243. * enter as ok and hilites the ok button.
  244. *
  245. * the ok button is always item 1.
  246. *
  247. * Notice that ModalDialog always accesses
  248. * this routine via a pointer.  If your
  249. * code implemented modalDialog in HandleHCEvent
  250. * then you will need to make sure that
  251. * XWHasInterrupt is set to true.
  252. ************************************/
  253. {
  254.     int                thenum;
  255.     Handle            theitem;
  256.     Rect            thebox;
  257.     char            cc;
  258.     
  259.     short            iTyp;
  260.     Handle            iHdl;
  261.     Rect            iBox;
  262.     ControlHandle    okbutn;
  263.     
  264.     switch( evt->what ){
  265.         case    keyDown:
  266.             cc = (char)evt->message & charCodeMask;
  267.             GetDItem( dlg, OK, &iTyp, &okbutn, &iBox);
  268.             if( (*okbutn)->contrlHilite != 255 ){
  269.                 SetCtlValue( okbutn, 1 );
  270.                 if(cc == CR || cc == ETX ){
  271.                     *itemhit = OK;
  272.                     return TRUE;
  273.                 }
  274.             }
  275.             break;
  276.             
  277.         case updateEvt:
  278.             GetDItem( dlg, OK, &iTyp, &okbutn, &iBox);
  279.             if( (*okbutn)->contrlHilite != 255 ){
  280.                 PenSize(3,3);
  281.                 InsetRect(&iBox,-4,-4);
  282.                 FrameRoundRect(&iBox,16,16);
  283.                 PenNormal();
  284.             }    
  285.             break;
  286.     }/* event switch */
  287.  
  288.     return    FALSE;
  289. }
  290.  
  291. pascal void HandleHCEvent( XCmdPtr    pp )
  292. /**********************************
  293. * Handle events in our xWindows    
  294. * returns true if the event was handled ok
  295. *
  296. **********************************/
  297. {
  298.     XWEventInfoPtr    ip    = pp->params[0];
  299.     WindowPtr        whichWindow;
  300.     short            windoPart;
  301.     TEHandle        hTE;
  302.     Rect            bounds;
  303.     Point            hit;
  304.     char            theKey;
  305.     GrafPtr            oldPort;
  306.     short            extend;
  307.     
  308.     pp->passFlag = TRUE;    /* seems to be more often the case */
  309.     
  310.     switch( ip->event.what ){
  311.     case mouseDown:
  312.         windoPart = FindWindow( ip->event.where, &whichWindow );
  313.             
  314.         if( whichWindow )
  315.             switch ( windoPart ){
  316.                 case inGoAway:
  317.                     if (TrackGoAway( whichWindow, ip->event.where) ){
  318.                         CLOSEXWINDOW( pp,whichWindow );
  319.                         pp->passFlag = FALSE;
  320.                     }
  321.                     break;
  322.  
  323.                 case inDrag:
  324.                     /* handled by hypercard */
  325.                     break;
  326.                     
  327.                 case inGrow:
  328.                 break;
  329.                     
  330.                 case inContent:
  331.                     if (whichWindow == FrontWindow() ){
  332.                         GetPort( &oldPort );
  333.                         SetPort( ip->eventWindow );
  334.                         
  335.                         SetPort( oldPort );
  336.                     }else
  337.                         SelectWindow( whichWindow );
  338.  
  339.                     pp->passFlag = FALSE;
  340.                     break;
  341.                 
  342.                 default: 
  343.                     break;
  344.             }/* window part */
  345.         break;
  346.         
  347.     case mouseUp:
  348.         break;
  349.                 
  350.     case keyDown:
  351.     case autoKey:    
  352.         /* the command key will be handled by hypercard */
  353.         GetPort( &oldPort );
  354.         SetPort( ip->eventWindow );
  355.         theKey  = ip->event.message & 0xFF;
  356.         
  357.         SetPort( oldPort );
  358.         pp->passFlag = FALSE;
  359.         break;
  360.         
  361.     case activateEvt:
  362.         if ( ip->event.modifiers & activeFlag )
  363.             BEGINXWEDIT( pp, ip->eventWindow );
  364.         else
  365.             ENDXWEDIT( pp, ip->eventWindow );
  366.         break;
  367.         
  368.     case updateEvt:
  369.         /* hypercard converts dialogs to 0x14 kind? */
  370.         if(((WindowPeek)(ip->eventWindow))->windowKind != 0x14) {
  371.             BeginUpdate( ip->eventWindow );
  372.             EndUpdate( ip->eventWindow );
  373.         }
  374.     break;
  375.         
  376.     case app4Evt:
  377.              {
  378.                  unsigned    char    *evtType = &(ip->event.message);
  379.                  
  380.                  switch( *evtType ){
  381.                      case MouseMovedEvt:
  382.                      break;
  383.                      
  384.                      case SuspendResumeEvt:
  385.                 break;
  386.                  }
  387.         }
  388.         break;
  389.  
  390.     /****************************************/
  391.     /*         THE HYPERCARD EVENTS            */
  392.     /****************************************/
  393.     case xOpenEvt:
  394.         SetPort( ip->eventWindow );
  395.         ShowWindow( ip->eventWindow );
  396.         break;
  397.             
  398.     case xCloseEvt:
  399.         HideWindow( ip->eventWindow );
  400.         break;
  401.     
  402.     case xGiveUpEditEvt:
  403.     break;
  404.  
  405.     case xEditUndo:
  406.     break;
  407.         
  408.     case xEditCut:
  409.     break;
  410.         
  411.     case xEditCopy:
  412.     break;
  413.         
  414.     case xEditPaste:
  415.     break;
  416.         
  417.     case xEditClear:
  418.     break;
  419.     
  420.     default:
  421.         GetPort( &oldPort );
  422.         SetPort( ip->eventWindow );
  423.         GetMouse( &hit );
  424.         
  425.         pp->passFlag = FALSE;
  426.         SetPort( oldPort );
  427.     }/* switch theEvent->what */
  428. }
  429.  
  430.  
  431.  
  432.